"use client"; // Next.js客户端组件标识
import { useState } from "react";
import "./globals.css"; // 全局样式

// 类型定义
type Square = "X" | "O" | null; // 单个格子状态
type Board = Square[]; // 棋盘类型（3x3 = 9个Square）

/**
 * 计算胜利者
 * @param squares 当前棋盘状态
 * @returns 返回胜利者（"X"/"O"）或null（无胜利者）
 */
const calculateWinner = (squares: Board): Square => {
  // 所有可能的胜利线组合（行、列、对角线）
  const lines = [
    [0, 1, 2],
    [3, 4, 5],
    [6, 7, 8], // 行
    [0, 3, 6],
    [1, 4, 7],
    [2, 5, 8], // 列
    [0, 4, 8],
    [2, 4, 6], // 对角线
  ];

  // 遍历所有胜利组合检查是否有相同符号
  for (const [a, b, c] of lines) {
    if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) {
      return squares[a];
    }
  }
  return null;
};

// 棋盘组件Props类型
interface BoardProps {
  xIsNext: boolean; // 是否轮到X玩家
  squares: Board; // 当前棋盘状态
  onPlay: (nextSquares: Board) => void; // 棋盘更新回调
  winner: Square; // 当前胜利者
  buindex: number; // 当前步数索引
}

/**
 * 棋盘组件
 * 处理格子点击事件和棋盘渲染
 */
const Board = ({ xIsNext, squares, onPlay, winner, buindex }: BoardProps) => {
  // 处理格子点击事件
  const handleClick = (i: number) => {
    // 如果格子已被占用或游戏已结束，阻止操作
    if (squares[i] || winner) return;

    // 创建新棋盘状态副本
    const nextSquares = squares.slice();
    nextSquares[i] = xIsNext ? "X" : "O";
    onPlay(nextSquares); // 触发父组件状态更新
  };

  // 状态显示文本
  const status = winner
    ? `Winner:${winner}` // 有胜利者时
    : buindex < 8
    ? `Next player:${xIsNext ? "X" : "O"}` // 游戏进行中
    : "平局"; // 棋盘已满无胜利者

  return (
    <div>
      <div className="status">{status}</div>
      {/* 生成3x3棋盘 */}
      <div className="board">
        {Array(3)
          .fill(null)
          .map((_, row) => (
            <div key={row} className="board-row">
              {Array(3)
                .fill(null)
                .map((__, col) => {
                  const index = row * 3 + col; // 计算格子索引（0-8）
                  return (
                    <button
                      key={index}
                      className="square"
                      onClick={() => handleClick(index)}
                    >
                      {squares[index]}
                    </button>
                  );
                })}
            </div>
          ))}
      </div>
    </div>
  );
};

/**
 * 游戏主组件
 * 管理游戏状态和历史记录
 */
const Game = () => {
  // 历史记录状态（包含所有棋盘状态）
  const [history, setHistory] = useState<Board[]>([Array(9).fill(null)]);
  const [currentMove, setCurrentMove] = useState(0); // 当前步数索引

  // 当前棋盘状态（从历史记录中获取）
  const currentSquares = history[currentMove];
  const xIsNext = currentMove % 2 === 0; // 根据步数判断当前玩家
  const winner = calculateWinner(currentSquares); // 计算当前胜利者

  /**
   * 处理棋盘更新
   * @param nextSquares 新的棋盘状态
   */
  const handlePlay=(nextSquares: Board)=> {
    // 截取到当前步数并添加新状态
    const nextHistory = [...history.slice(0, currentMove + 1), nextSquares];
    setHistory(nextHistory);
    setCurrentMove(nextHistory.length - 1); // 更新到最新步数
  }

  /**
   * 跳转到指定历史步骤
   * @param nextMove 目标步数索引
   */
  const jumpTo=(nextMove: number) =>{
    setCurrentMove(nextMove);
  }

  /** 悔棋功能（回到上一步） */
  const handleUndo=() =>{
    if (currentMove > 0) {
      setCurrentMove(currentMove - 1);
    }
  }

  // 生成历史步骤列表
  const moves = history.map((_, move) => {
    const description = move > 0 ? `前往第 ${move} 步` : "游戏开始";
    return (
      <li key={move}>
        <button onClick={() => jumpTo(move)}>{description}</button>
      </li>
    );
  });

  return (
    <div className="game">
      <div className="game-board">
        <Board
          xIsNext={xIsNext}
          squares={currentSquares}
          onPlay={handlePlay}
          winner={winner}
          buindex={currentMove}
        />
      </div>
      <div className="game-info">
        {/* 悔棋按钮（第一步时禁用） */}
        <button
          onClick={handleUndo}
          disabled={currentMove === 0}
          className="undo-button"
        >
          悔棋
        </button>
        {/* 历史记录列表 */}
        <ol>{moves}</ol>
      </div>
    </div>
  );
};

export default Game;
